<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <meta
            name="viewport"
            content="width=device-width, minimal-ui, viewport-fit=cover, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"
        />
        <link rel="icon" type="image/png" href="assets/favicon.png" />

        <title>OGL • Triangle Screen Shader</title>
        <link href="assets/main.css" rel="stylesheet" />
    </head>
    <body>
        <div class="Info">Triangle Screen Shader</div>
        <script type="module">
            import { Renderer, Program, Color, Mesh, Triangle } from '../src/index.mjs';

            const vertex = /* glsl */ `
                attribute vec2 uv;
                attribute vec2 position;

                varying vec2 vUv;

                void main() {
                    vUv = uv;
                    gl_Position = vec4(position, 0, 1);
                }
            `;

            const fragment = /* glsl */ `
                precision highp float;

                uniform float uTime;
                uniform vec3 uColor;

                varying vec2 vUv;

                void main() {
                    gl_FragColor.rgb = 0.5 + 0.3 * cos(vUv.xyx + uTime) + uColor;
                    gl_FragColor.a = 1.0;
                }
            `;

            {
                const renderer = new Renderer();
                const gl = renderer.gl;
                document.body.appendChild(gl.canvas);
                gl.clearColor(1, 1, 1, 1);

                function resize() {
                    renderer.setSize(window.innerWidth, window.innerHeight);
                }
                window.addEventListener('resize', resize, false);
                resize();

                // Rather than using a plane (two triangles) to cover the viewport here is a
                // triangle that includes -1 to 1 range for 'position', and 0 to 1 range for 'uv'.
                // Excess will be out of the viewport.

                //         position                uv
                //      (-1, 3)                  (0, 2)
                //         |\                      |\
                //         |__\(1, 1)              |__\(1, 1)
                //         |__|_\                  |__|_\
                //   (-1, -1)   (3, -1)        (0, 0)   (2, 0)

                const geometry = new Triangle(gl);

                const program = new Program(gl, {
                    vertex,
                    fragment,
                    uniforms: {
                        uTime: { value: 0 },
                        uColor: { value: new Color(0.3, 0.2, 0.5) },
                    },
                });

                const mesh = new Mesh(gl, { geometry, program });

                requestAnimationFrame(update);
                function update(t) {
                    requestAnimationFrame(update);

                    program.uniforms.uTime.value = t * 0.001;

                    // Don't need a camera if camera uniforms aren't required
                    renderer.render({ scene: mesh });
                }
            }
        </script>
    </body>
</html>
